using System;
using System.IO;
using System.Diagnostics;
using System.Collections.Generic;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Framework;

namespace Pavilion.DesignerTool
{
    public class ContentBuilder
    {
        private const string xnaVersion = ", Version=4.0.0.0, PublicKeyToken=842cf8be1de50553";

        private static readonly string[] pipelineAssemblies =
        {
            "Microsoft.Xna.Framework.Content.Pipeline.AudioImporters" + xnaVersion,
            "Microsoft.Xna.Framework.Content.Pipeline.EffectImporter" + xnaVersion,
            "Microsoft.Xna.Framework.Content.Pipeline.FBXImporter" + xnaVersion,
            "Microsoft.Xna.Framework.Content.Pipeline.TextureImporter" + xnaVersion,
            "Microsoft.Xna.Framework.Content.Pipeline.VideoImporters" + xnaVersion,
            "Microsoft.Xna.Framework.Content.Pipeline.XImporter" + xnaVersion,
        };

        private ProjectCollection projectCollection;
        private Project project;
        private List<ProjectItem> projectItems;
        private ErrorLogger errorLogger;

        public ContentBuilder(string buildPath)
        {
            projectItems = new List<ProjectItem>();
            ConfigureBuildProject(buildPath);
        }

        public void Dispose()
        {
            projectItems.Clear();
            projectCollection.Dispose();

            project.RemoveItems(project.GetItems("Compile"));

            project.RemoveProperty(project.GetProperty("XnaPlatform"));
            project.RemoveProperty(project.GetProperty("XnaFrameworkVersion"));
            project.RemoveProperty(project.GetProperty("XnaProfile"));
            project.RemoveProperty(project.GetProperty("Configuration"));
            project.Xml.RemoveAllChildren();
           // project.RemoveProperty(project.GetProperty("OutputPath"));

            errorLogger = null;
            project = null;
            projectCollection = null;
        }

        private void ConfigureBuildProject(string buildDirectory)
        {
            string projectPath = buildDirectory;
            string outputPath = Directory.GetParent(buildDirectory).FullName;

            // Create the project collection
            projectCollection = new ProjectCollection();

            // Hook up our custom error logger.
            errorLogger = new ErrorLogger();
            projectCollection.RegisterLogger(errorLogger);

            // Create the build project.
            project = new Project(projectCollection);
            project.FullPath = projectPath;

            // set up the properties we care about
            project.SetProperty("XnaPlatform", "Windows");
            project.SetProperty("XnaFrameworkVersion", "v4.0");
            project.SetProperty("XnaProfile", "Reach");//Other one is HiDef???...maybe...google it to make sure.
            project.SetProperty("Configuration", "Release");
            project.SetProperty("OutputPath", outputPath);

            // Register any custom importers or processors.
            foreach (string pipelineAssembly in pipelineAssemblies)
            {
                project.AddItem("Reference", pipelineAssembly);
            }

            // Include the standard targets file that defines
            // how to build XNA Framework content.
            project.Xml.AddImport(
                "$(MSBuildExtensionsPath)\\Microsoft\\XNA Game Studio\\v4.0\\" +
                "Microsoft.Xna.GameStudio.ContentPipeline.targets");
        }

        public void Save()
        {
            string[] resourcePathList = Directory.GetDirectories(GameEngine.AnimationsDirectory);

            foreach (string resourcePath in resourcePathList)
            {
                string objPath = GameEngine.AnimationsDirectory + @"obj";
                if (resourcePath == objPath || !Directory.Exists(resourcePath + @"\Raw Data"))
                    continue;

                string[] animationPathList = Directory.GetDirectories(resourcePath + @"\Raw Data");
                string resourceName = new DirectoryInfo(resourcePath).Name;

                foreach (string animationPath in animationPathList)
                {
                    string[] framePathList = Directory.GetDirectories(animationPath);
                    string animationName = new DirectoryInfo(animationPath).Name;

                    foreach (string framePath in framePathList)
                    {
                        string[] textureFilePathList = Directory.GetFiles(framePath);
                        string frameName = new DirectoryInfo(framePath).Name;

                        foreach (string testureFilePath in textureFilePathList)
                        {
                            string fileName = Path.GetFileName(testureFilePath);
                            fileName = fileName.Substring(0, fileName.IndexOf('.'));
                            Add(testureFilePath, resourceName + @"\Built Data\" + animationName + @"\" + frameName + @"\" + fileName, null, null);
                        }
                    }
                }
            }

            Build();
        }

        public void ConvertAnimations()
        {
            string buildDirectory = @"C:\Users\vahid.rujevic\Desktop\Vrujevic\Game Development\The Farthest Land Directory\PavilionDesignerTool\Pavilion.DesignerTool\Content\GameResources\Animations";

            string[] resourcePathList = Directory.GetDirectories(buildDirectory);
            //ConfigureBuildProject(buildDirectory);

            foreach (string resourcePath in resourcePathList)
            {
                string[] animationPathList = Directory.GetDirectories(resourcePath + @"\Raw Data");
                string resourceName = new DirectoryInfo(resourcePath).Name;

                foreach (string animationPath in animationPathList)
                {
                    string[] frameList = Directory.GetFiles(animationPath);
                    string animationName = new DirectoryInfo(animationPath).Name;
                    
                    foreach (string frame in frameList)
                    {
                        string fileName = Path.GetFileName(frame);
                        fileName = fileName.Substring(0, fileName.IndexOf('.'));
                        Add(frame, resourceName + @"\Built Data\" + animationName + @"\" + fileName, null, null);
                    }
                }
            }

            Build();
        }

        public void ConvertEnvironment()
        {
            string buildDirectory = @"C:\Users\vahid.rujevic\Desktop\Vrujevic\Game Development\The Farthest Land Directory\PavilionDesignerTool\Pavilion.DesignerTool\Content\GameResources\Environments";

            string[] resourcePathList = Directory.GetDirectories(buildDirectory);
            //ConfigureBuildProject(buildDirectory);

            foreach (string resourcePath in resourcePathList)
            {
                string[] layerPathList = Directory.GetDirectories(resourcePath + @"\Raw Data");
                string resourceName = new DirectoryInfo(resourcePath).Name;

                foreach (string layerPath in layerPathList)
                {
                    string[] frameFolderList = Directory.GetDirectories(layerPath);
                    string layerName = new DirectoryInfo(layerPath).Name;

                    foreach (string frameFolderPath in frameFolderList)
                    {
                        string[] frameList = Directory.GetFiles(frameFolderPath);
                        string frameFolderName = new DirectoryInfo(frameFolderPath).Name;

                        foreach (string frame in frameList)
                        {
                            string fileName = Path.GetFileName(frame);
                            fileName = fileName.Substring(0, fileName.IndexOf('.'));
                            Add(frame, resourceName + @"\Built Data\" + layerName + @"\" + frameFolderName + @"\"+ fileName, null, null);
                        }
                    }
                }
            }

            Build();
        }

        public void Add(string filename, string name, string importer, string processor)
        {
            string name2 = Path.GetFileName(filename);
            string m = name2;
            //set up the metadata for this item
            var metadata = new SortedList<string, string>();
            metadata.Add("Link", Path.GetFileName(filename));
            metadata.Add("Name", name);

            if (!string.IsNullOrEmpty(importer))
                metadata.Add("Importer", importer);

            if (!string.IsNullOrEmpty(processor))
                metadata.Add("Processor", processor);

            // add the item
            project.AddItem("Compile", filename, metadata);
        }

        public bool Build()
        {
            errorLogger.Errors.Clear();
            return project.Build();
        }

        private class ErrorLogger : ILogger
        {
            public List<string> Errors { get; private set; }
            public string Parameters { get; set; }
            public LoggerVerbosity Verbosity { get; set; }

            public ErrorLogger()
                : base()
            {
                Verbosity = LoggerVerbosity.Normal;
                Errors = new List<string>();
            }

            public void Initialize(IEventSource eventSource)
            {
                if (eventSource != null)
                {
                    eventSource.ErrorRaised += EventSource_ErrorRaised;
                }
            }

            public void Shutdown() { }

            private void EventSource_ErrorRaised(object sender, BuildErrorEventArgs e)
            {
                Errors.Add(e.Message);
            }
        }
    }
}
